package com.lion.seaman.common.tools;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * 时间处理类
 *
 * @author 李永曜 2015年6月17日
 */
public class TimeTools {

    public static SimpleDateFormat getSdf(Format format) {
        return getSdf(format.text);
    }

    public static SimpleDateFormat getSdf(String format) {
        return new SimpleDateFormat(format);
    }

    /**
     * 使用指定format格式化时间
     *
     * @param date
     * @param format
     * @return
     */
    public static String getDateString(Date date, Format format) {
        return getSdf(format).format(date);
    }

    public static String getDateString(int hourOffset, Format format) {
        return getSdf(format).format(hourOffset(hourOffset).getTime());
    }

    /**
     * 使用指定format 字符串格式化时间
     *
     * @param date
     * @param format
     * @return
     */
    public static String getDateString(Date date, String format) {
        return getSdf(format).format(date);
    }

    /**
     * 通过字符串及格式获得时间对象
     *
     * @param dateString
     * @param format
     * @return
     */
    public static Date parseDateString(String dateString, Format format) {
        try {
            return getSdf(format).parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过字符串及格式获得时间对象
     *
     * @param dateString
     * @param formatPattern
     * @return
     */
    public static Date parseDateString(String dateString, String formatPattern) {
        try {
            return getSdf(formatPattern).parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 判断两个日期是否是同一天
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDate(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear
                && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
        boolean isSameDate = isSameMonth
                && cal1.get(Calendar.DAY_OF_MONTH) == cal2
                .get(Calendar.DAY_OF_MONTH);
        return isSameDate;
    }

    public static boolean isSameHour(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear
                && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
        boolean isSameDate = isSameMonth
                && cal1.get(Calendar.DAY_OF_MONTH) == cal2
                .get(Calendar.DAY_OF_MONTH);
        boolean isSameHour = isSameDate && cal1.get(Calendar.HOUR_OF_DAY) == cal2.get(Calendar.HOUR_OF_DAY);
        return isSameHour;
    }

    /**
     * 判断当前时间是否在指定时间段内
     *
     * @param startTime 开始时间
     * @param overTime  结束时间
     * @return true, 在;false,不在
     */
    public static boolean isWithinBetweenDate(Date startTime, Date overTime) {
        long nowTimeLong = new Date().getTime();
        long ckStartTimeLong = startTime.getTime();
        long ckOverTimeLong = overTime.getTime();
        if (nowTimeLong > ckStartTimeLong && nowTimeLong < ckOverTimeLong) {
            return true;
        }
        return false;
    }

    /**
     * long时间转换为时间字符串
     *
     * @param time
     * @return
     */
    public static String parseLong2DateString(long time, Format format) {
        try {
            Date date = new Date(time);
            return getDateString(date, format);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 日期偏移
     *
     * @param offset 正向后偏移，负向前偏移
     * @return
     */
    public static Calendar dateOffset(int offset) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, offset);
        return cal;
    }

    /**
     * 小时偏移
     *
     * @param offset
     * @return
     */
    public static Calendar hourOffset(int offset) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.HOUR, offset);
        return cal;
    }

    public static int getYear(Calendar calendar) {
        return calendar.get(Calendar.YEAR);
    }

    public static int getMonth(Calendar calendar) {
        return calendar.get(Calendar.MONTH);
    }

    public static int getDay(Calendar calendar) {
        return calendar.get(Calendar.DAY_OF_YEAR);
    }

    public static int getHour(Calendar calendar) {
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    public static int getMinute(Calendar calendar) {
        return calendar.get(Calendar.MINUTE);
    }

    public static int getSecond(Calendar calendar) {
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 时区 时间转换方法:将当前时间（可能为其他时区）转化成目标时区对应的时间
     *
     * @param sourceTime 时间格式必须为：yyyy-MM-dd HH:mm:ss
     * @param sourceId   入参的时间的时区id(eg:GMT)
     * @param targetId   要转换成目标时区id（eg:GTM+8）
     * @return string 转化时区后的时间
     */
    public static String timeConvert(String sourceTime, String sourceId,
                                     String targetId) {
        // 校验入参是否合法
        if (StringTools.isBlank(sourceTime, sourceId, targetId)) {
            return "";
        }
        // 校验 时间格式必须为：yyyy-MM-dd HH:mm:ss
        String reg = "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$";
        if (!sourceTime.matches(reg)) {
            return "";
        }

        try {
            // 时间格式
            SimpleDateFormat df = new SimpleDateFormat(Format.DATETIME.getText());
            // 根据入参原时区id，获取对应的timezone对象
            TimeZone sourceTimeZone = TimeZone.getTimeZone(sourceId);
            // 设置SimpleDateFormat时区为原时区（否则是本地默认时区），目的:用来将字符串sourceTime转化成原时区对应的date对象
            df.setTimeZone(sourceTimeZone);
            // 将字符串sourceTime转化成原时区对应的date对象
            Date sourceDate = df.parse(sourceTime);

            // 开始转化时区：根据目标时区id设置目标TimeZone
            TimeZone targetTimeZone = TimeZone.getTimeZone(targetId);
            // 设置SimpleDateFormat时区为目标时区（否则是本地默认时区），目的:用来将字符串sourceTime转化成目标时区对应的date对象
            df.setTimeZone(targetTimeZone);
            // 得到目标时间字符串
            String targetTime = df.format(sourceDate);
            return targetTime;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";

    }

    /**
     * 分钟偏移
     *
     * @param offset 正向后偏移，负向前偏移
     * @return
     */
    public static Date minuteOffset(int offset) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, offset);
        return cal.getTime();
    }

    /**
     * 分钟偏移
     *
     * @param source
     * @param offset
     * @return
     */
    public static Date minuteOffset(Date source, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(source);
        cal.add(Calendar.MINUTE, offset);
        return cal.getTime();
    }

    /**
     * 计算分钟间隔,秒位，毫秒位归零计算
     *
     * @param time1
     * @param time2
     * @return
     */
    public static long minuteInterval(Date time1, Date time2) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(time1);
        calendar1.set(Calendar.SECOND, 0);
        calendar1.set(Calendar.MILLISECOND, 0);

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(time2);
        calendar2.set(Calendar.SECOND, 0);
        calendar2.set(Calendar.MILLISECOND, 0);

        long cha = calendar1.getTimeInMillis() - calendar2.getTimeInMillis();
        long miao = cha / 1000 / 60;
        return miao;
    }


    public static void main(String[] args) {
        String time = timeConvert("2016-12-16 00:00:00", "GMT+8", "GMT");
        System.out.printf(time);
    }

    /**
     * 格式枚举
     *
     * @author 李永曜 2015年6月17日
     */
    public enum Format {

        SHORT("ddHHmmss"), DATE("yyyy-MM-dd"), DATENOLINE("yyyyMMdd"), DATETIME(
                "yyyy-MM-dd HH:mm:ss"), DATETIME1("yyyyMMddHHmmss"), DATEHOUR("yyyyMMddHH"), HOUR("HH");

        private String text;

        private Format(String text) {
            this.text = text;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

    }

}
